from wx import wx
import Image
import ImageDraw
import StringIO
import base64

class CropImageDialog(wx.Dialog):
    def __init__(self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE, useMetal=False,):
        # Instead of calling wx.Dialog.__init__ we precreate the dialog
        # so we can set an extra style that must be set before
        # creation, and then we create the GUI object using the Create
        # method.
        pre = wx.PreDialog()
        pre.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
        pre.Create(parent, ID, title, pos, size, style)

        # This next step is the most important, it turns this Python
        # object into the real wrapper of the dialog (instead of pre)
        # as far as the wxPython extension is concerned.
        self.PostCreate(pre)

        # This extra style can be set after the UI object has been created.
        if 'wxMac' in wx.PlatformInfo and useMetal:
            self.SetExtraStyle(wx.DIALOG_EX_METAL)


        # Now continue with the normal construction of the dialog
        # contents
        self.inString = StringIO.StringIO()
        tmpString = self.GetParent().imageListBox.GetStringSelection()
        tmpString2 = tmpString.split(".", 1)
        self.data = base64.decodestring(self.GetParent().TopLevelParent.currentImageDict[int(tmpString2[0])][0])
        self.inString.write(self.data)
        self.inString.seek(0)
        self.originalImage = Image.open(self.inString)
        self.inString.close()
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        topBox = wx.BoxSizer(wx.HORIZONTAL)
        leftBox = wx.BoxSizer(wx.VERTICAL)
        tBox = wx.GridSizer(1, 6, 1, 1)
        # tBox = wx.BoxSizer(wx.HORIZONTAL)
        # bBox = wx.BoxSizer(wx.HORIZONTAL)
        bBox = wx.GridSizer(1, 6, 1, 1)
        botBox = wx.BoxSizer(wx.HORIZONTAL)        
        self.leftSpinner = wx.SpinCtrl(self, -1, size=(50, 20))
        self.topSpinner = wx.SpinCtrl(self, -1, size=(50, 20))
        self.rightSpinner = wx.SpinCtrl(self, -1, size=(50, 20))
        self.bottomSpinner = wx.SpinCtrl(self, -1, size=(50, 20))
        self.previewPanel = wx.Panel(self)
        self.lText = wx.StaticText(self, -1, "Left: ")
        self.tText = wx.StaticText(self, -1, " Top: ")
        self.rText = wx.StaticText(self, -1, "Right: ")
        self.bText = wx.StaticText(self, -1, " Bottom: ")
        self.pText1 = wx.StaticText(self, -1, " px ")
        self.pText2 = wx.StaticText(self, -1, " px ")
        self.pText3 = wx.StaticText(self, -1, " px ")
        self.pText4 = wx.StaticText(self, -1, " px ")
        
        self.previewPanel.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
        
        self.DrawPreviewImage(1, 1, 1, 1)
        
        self.leftSpinner.SetRange(0, self.originalImage.size[0])
        self.topSpinner.SetRange(0, self.originalImage.size[1])
        self.rightSpinner.SetRange(0, self.originalImage.size[0])
        self.bottomSpinner.SetRange(0, self.originalImage.size[1])
        
        wx.EVT_SPINCTRL(self, self.leftSpinner.GetId(), self.OnLeftSpin)
        wx.EVT_SPINCTRL(self, self.topSpinner.GetId(), self.OnTopSpin)
        wx.EVT_SPINCTRL(self, self.rightSpinner.GetId(), self.OnRightSpin)
        wx.EVT_SPINCTRL(self, self.bottomSpinner.GetId(), self.OnBottomSpin)
        
        
        topStaticBox = wx.StaticBox(self, -1, "Crop")
        topStaticBoxSizer = wx.StaticBoxSizer(topStaticBox)
        bottomStaticBox = wx.StaticBox(self, -1, "Preview")
        bottomStaticBoxSizer = wx.StaticBoxSizer(bottomStaticBox)
        
        tBox.Add(self.lText, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        tBox.Add(self.leftSpinner, 0, wx.ALL)
        tBox.Add(self.pText1, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        tBox.Add(self.tText, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        tBox.Add(self.topSpinner, 0, wx.ALL)
        tBox.Add(self.pText2, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        bBox.Add(self.rText, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        bBox.Add(self.rightSpinner, 0, wx.ALL)
        bBox.Add(self.pText3, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        bBox.Add(self.bText, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        bBox.Add(self.bottomSpinner, 0, wx.ALL)
        bBox.Add(self.pText4, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL)
        leftBox.Add(tBox, 0, wx.ALL)
        leftBox.Add(bBox, 0, wx.ALL)
        topBox.Add(leftBox, 0, wx.ALL)
        botBox.Add(self.previewPanel, 1, wx.EXPAND)
        topStaticBoxSizer.Add(topBox, 0, wx.ALL)
        bottomStaticBoxSizer.Add(botBox, 0, wx.ALL)
        sizer.Add(topStaticBoxSizer, 0, wx.ALL)
        sizer.Add(bottomStaticBoxSizer, 1, wx.EXPAND)
        
        line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
        sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)

        btnsizer = wx.StdDialogButtonSizer()
        
        if wx.Platform != "__WXMSW__":
            btn = wx.ContextHelpButton(self)
            btnsizer.AddButton(btn)
        
        btn = wx.Button(self, wx.ID_OK)
        btn.SetHelpText("The OK button completes the dialog")
        btn.SetLabel("Crop")
        btn.SetDefault()
        btnsizer.AddButton(btn)

        btn = wx.Button(self, wx.ID_CANCEL)
        btn.SetHelpText("The Cancel button cancels the dialog.")
        btnsizer.AddButton(btn)
        btnsizer.Realize()

        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)

        self.SetSizer(sizer)
        sizer.Fit(self)
        
    def OnLeftSpin(self, event):
        self.DrawPreviewImage(self.leftSpinner.GetValue(), self.topSpinner.GetValue(), self.rightSpinner.GetValue(), self.bottomSpinner.GetValue())
        
    def OnTopSpin(self, event):
        self.DrawPreviewImage(self.leftSpinner.GetValue(), self.topSpinner.GetValue(), self.rightSpinner.GetValue(), self.bottomSpinner.GetValue())
        
    def OnRightSpin(self, event):
        self.DrawPreviewImage(self.leftSpinner.GetValue(), self.topSpinner.GetValue(), self.rightSpinner.GetValue(), self.bottomSpinner.GetValue())
        
    def OnBottomSpin(self, event):
        self.DrawPreviewImage(self.leftSpinner.GetValue(), self.topSpinner.GetValue(), self.rightSpinner.GetValue(), self.bottomSpinner.GetValue())
        
    def DrawPreviewImage(self, curL, curT, curR, curB):
        self.inString = StringIO.StringIO()
        tmpString = self.GetParent().imageListBox.GetStringSelection()
        tmpString2 = tmpString.split(".", 1)
        self.data = base64.decodestring(self.GetParent().TopLevelParent.currentImageDict[int(tmpString2[0])][0])
        self.inString.write(self.data)
        self.inString.seek(0)
        self.displayImage = Image.open(self.inString)
        draw = ImageDraw.Draw(self.displayImage)
        draw.rectangle((curL, curT, self.displayImage.size[0] - curR, self.displayImage.size[1] - curB), outline=(255, 0, 0))
        
        self.GetParent().ShowBitmapFromPIL(self.previewPanel, self.displayImage)        